package com.junchenrobot.mes.manager;

import com.junchenrobot.mes.client.KCClient;
import com.junchenrobot.mes.core.TaskScheduled;
import com.junchenrobot.mes.dao.AgvWorkDao;
import com.junchenrobot.mes.dao.DeviceDao;
import com.junchenrobot.mes.dao.WinderDao;
import com.junchenrobot.mes.dao.WinderTaskDao;
import com.junchenrobot.mes.domain.WinderTask;
import com.junchenrobot.mes.dto.ResultDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;

/**
 * rcs 管理类
 *
 * @author SeaWave
 */
@Slf4j
@Component
public class RcsManager {
    
    private final AgvWorkDao agvWorkDao;
    
    
    private final WinderTaskDao winderTaskDao;
    
    private final WinderDao winderDao;
    
    private final KCClient kcClient;
    
    private final DeviceDao deviceDao;
    
    private final WinderManager winderManager;
    
    private final TaskScheduled scheduled;
    
    private final Map<String, ResultDto> taskMap = new ConcurrentHashMap<>();
    
    
    @Autowired
    public RcsManager(WinderTaskDao winderTaskDao, AgvWorkDao agvWorkDao, WinderDao winderDao, KCClient kcClient,
                      DeviceDao deviceDao, WinderManager winderManager, TaskScheduled scheduled) {
        this.winderTaskDao = winderTaskDao;
        this.agvWorkDao = agvWorkDao;
        this.winderDao = winderDao;
        this.kcClient = kcClient;
        this.deviceDao = deviceDao;
        this.winderManager = winderManager;
        this.scheduled = scheduled;
    }
    
    
    /**
     * 确认装载任位置到位
     * 车到位后执行 修改任务执行状态
     * 更新作业为到位型号
     * 循环查询是否为可以接货状态
     *
     * @param taskNo 任务编号
     * @return {@link Future}<{@link Boolean}>
     */
    public Future<Boolean> confirmInputInPlace(String taskNo) {
        if (!taskMap.containsKey(taskNo)) {
            ResultDto resultDto = new ResultDto();
            resultDto.setState("1");
            resultDto.setFinished(new int[6]);
            taskMap.put(taskNo, resultDto);
        }
        ResultDto resultDto = taskMap.get(taskNo);
        int[] finished = resultDto.getFinished();
        if (finished[0] == 1) {
            return new AsyncResult<>(Boolean.TRUE);
        }
        
        WinderTask task = winderTaskDao.getTask(taskNo);
        Long taskWinderId = task.getTaskWinderId();
        agvWorkDao.updateWorkStatus(taskWinderId, 2);
        // TODO
        //Integer offset = winderDao.selectOffset(task.getTaskWinderLine().toString(),
        //        task.getTaskWinderSpinningCode().toString());
        //// 执行查看是否准备好
        //winderManager.winderReady(taskWinderId, offset);
        
        // 完成任务
        finished[0] = 1;
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    /**
     * 开始推丝信号
     * 车推杆动作结束后执行 确认是否有手动推杆信号 有的通知第三方开始做推动作并返回正确信息 无则返回错误信息
     *
     * @param taskNo 任务编号
     * @return {@link Future }<{@link Boolean}>
     */
    public Future<Boolean> startPush(String taskNo) {
        if (!taskMap.containsKey(taskNo)) {
            ResultDto resultDto = new ResultDto();
            resultDto.setState("2");
            resultDto.setFinished(new int[7]);
            taskMap.put(taskNo, resultDto);
        }
        ResultDto resultDto = taskMap.get(taskNo);
        int[] finished = resultDto.getFinished();
        if (finished[1] == 1) {
            return new AsyncResult<>(Boolean.TRUE);
        }
        WinderTask task = winderTaskDao.getTask(taskNo);
        // TODO
        //Integer offset = winderDao.selectOffset(task.getTaskWinderLine().toString(),
        //        task.getTaskWinderSpinningCode().toString());
        //log.info("偏移量{}", offset);
        //// 循环读取偏移量 动推丝");
        //winderManager.winderPush(offset);
        finished[1] = 1;
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    
    /**
     * 动作结束
     * 第三方动作结束后执行 动作结束后
     *
     * @param taskNo 任务编号
     * @return {@link Future}<{@link Boolean}>
     */
    public Future<Boolean> inputActionFinished(String taskNo) {
        if (!taskMap.containsKey(taskNo)) {
            ResultDto resultDto = new ResultDto();
            resultDto.setState("3");
            resultDto.setFinished(new int[7]);
            taskMap.put(taskNo, resultDto);
        }
        ResultDto resultDto = taskMap.get(taskNo);
        int[] finished = resultDto.getFinished();
        if (finished[2] == 1) {
            return new AsyncResult<>(Boolean.TRUE);
        }
        
        WinderTask task = winderTaskDao.getTask(taskNo);
        // 更新为结束状态
        task.setTaskExecuteStatus(1);
        winderTaskDao.updateTaskById(task);
        agvWorkDao.updateWorkStatus(task.getTaskWinderId(), 5);
        // 调度任务
        //scheduled.scheduleWinderTask();
        
        finished[2] = 1;
        // TODO
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    
    /**
     * 确认卸载任务位置到位
     *
     * @param taskNo 任务编号
     * @return {@link Future}<{@link Boolean}>
     */
    public Future<Boolean> confirmOutputInPlace(String taskNo) {
        if (!taskMap.containsKey(taskNo)) {
            ResultDto resultDto = new ResultDto();
            resultDto.setState("4");
            resultDto.setFinished(new int[7]);
            taskMap.put(taskNo, resultDto);
        }
        ResultDto resultDto = taskMap.get(taskNo);
        int[] finished = resultDto.getFinished();
        if (finished[3] == 1) {
            return new AsyncResult<>(Boolean.TRUE);
        }
        
        log.info("等待取货请求");
        
        WinderTask task = winderTaskDao.getTask(taskNo);
        Integer taskPoleCode = task.getTaskPoleCode();
        Integer taskWinderSpinningCode = task.getTaskWinderSpinningCode();
        String taskWinderLsh = task.getTaskWinderLsh();
        Integer taskWinderLine = task.getTaskWinderLine();
        // 任务
        finished[3] = 1;
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    /**
     * 确认卸载任务位置到位
     *
     * @param taskNo 任务编号
     * @return {@link Future}<{@link Boolean}>
     */
    public Future<Boolean> cancel(String taskNo) {
        WinderTask task = winderTaskDao.getTask(taskNo);
        task.setTaskExecuteStatus(2);
        task.setTaskRemark("取消任务");
        // 更新结束态
        winderTaskDao.updateTaskById(task);
        agvWorkDao.updateWorkStatus(task.getTaskWinderId(), 6);
        kcClient.pauseRunningTask(taskNo);
        kcClient.cancelRunningTask(taskNo);
        kcClient.resetDevice(task.getTaskDeviceName());
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    /**
     * 卸载任务动作结束
     * 卸载任务结束后执行
     *
     * @param taskNo 任务编号
     * @return {@link Future}<{@link Boolean}>
     */
    public Future<Boolean> outPutActionFinished(String taskNo) {
        if (!taskMap.containsKey(taskNo)) {
            ResultDto resultDto = new ResultDto();
            resultDto.setState("5");
            resultDto.setFinished(new int[7]);
            taskMap.put(taskNo, resultDto);
        }
        ResultDto resultDto = taskMap.get(taskNo);
        int[] finished = resultDto.getFinished();
        if (finished[4] == 1) {
            return new AsyncResult<>(Boolean.TRUE);
        }
        
        // todo
        WinderTask task = winderTaskDao.getTask(taskNo);
        
        log.info("写入完成");
        finished[4] = 1;
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    /**
     * 更新大门状态
     *
     * @param action 动作
     * @param gateNo 大门编号
     * @return {@link Future}<{@link Boolean}>
     */
    public Future<Boolean> updateGateState(String gateNo, Integer action) {
        // TODO
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    
    public Future<Boolean> taskFinished(String taskNo) {
        if (!taskMap.containsKey(taskNo)) {
            ResultDto resultDto = new ResultDto();
            resultDto.setState("6");
            resultDto.setFinished(new int[6]);
            taskMap.put(taskNo, resultDto);
        }
        ResultDto resultDto = taskMap.get(taskNo);
        int[] finished = resultDto.getFinished();
        if (finished[5] == 1) {
            return new AsyncResult<>(Boolean.TRUE);
        }
        
        WinderTask task = winderTaskDao.getTask(taskNo);
        task.setTaskExecuteStatus(2);
        winderTaskDao.updateTaskById(task);
        // 更改设备负载状态
        log.info("____修改车状态3:设为0___");
        deviceDao.updateDevicePoleStatus(task.getTaskDeviceName(), task.getTaskPoleCode(), 0);
        log.info("____修改车状态3:设为0ok___");
        // 调度任务
        //scheduled.scheduleOutputWinderTask(task.getTaskDeviceName());
        finished[5] = 1;
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    
    public Future<Boolean> state(String taskNo) {
        // TODO
        return new AsyncResult<>(Boolean.TRUE);
    }
    
    
}
